use rusqlite::{Connection, Error, Result, params};

pub struct Database {
    conn: Connection,
}
impl Database {
    pub fn new(file_path: impl AsRef<std::path::Path>) -> Result<Database, Error> {
        let conn = Connection::open(file_path)?;
        Ok(Database { conn })
    }
    pub fn create_user_table(&mut self) -> Result<()> {
        self.conn.execute(
            "CREATE TABLE IF NOT EXISTS user (
                id TEXT PRIMARY KEY,
                name TEXT NOT NULL,
                password TEXT NOT NULL,
                key TEXT NOT NULL,
                client_id TEXT NOT NULL
            )",
            params![],
        )?;
        Ok(())
    }
    pub fn query_all_users(&mut self) -> Result<Vec<User>, Error> {
        let mut stmt = self
            .conn
            .prepare("SELECT id, name , password,key,client_id FROM user")?;
        let session_iter = stmt.query_map([], |row| {
            Ok(User {
                id: row.get(0)?,
                name: row.get(1)?,
                password: row.get(2)?,
                key: row.get(3)?,
                client_id: row.get(4)?,
            })
        })?;
        let mut sessions = Vec::new();
        for session_result in session_iter {
            sessions.push(session_result?);
        }
        Ok(sessions)
    }
    pub fn insert_user(&mut self, user: &User) -> Result<u64, Error> {
        self.conn.execute(
            "INSERT INTO user (id, name, password, key, client_id) VALUES (?1, ?2, ?3, ?4, ?5)",
            params![user.id, user.name, user.password, user.key, user.client_id],
        )?;
        Ok(1)
    }
    pub fn delete_user(&mut self, id: &str) -> Result<u64, Error> {
        self.conn
            .execute("DELETE FROM user WHERE id = ?1", params![id])?;
        Ok(1)
    }
}

#[derive(Debug, Clone)]
pub struct User {
    id: String,
    name: String,
    password: String,
    key: String,       // 设备密钥
    client_id: String, // 客户端ID
}
impl User {
    pub fn new(id: String, name: String, password: String, key: String, client_id: String) -> Self {
        Self {
            id,
            name,
            password,
            key,
            client_id,
        }
    }
    pub fn get_id(&self) -> &str {
        &self.id
    }
    pub fn get_name(&self) -> &str {
        &self.name
    }
    pub fn get_password(&self) -> &str {
        &self.password
    }
    pub fn get_key(&self) -> &str {
        &self.key
    }
    pub fn get_client_id(&self) -> &str {
        &self.client_id
    }
}
